package com.example.demo.leetcode;
// 组合
/**
 * 找出所有相加之和为 n 的 k 个数的组合，且满足下列条件：
 * <p>
 * 只使用数字1到9
 * 每个数字 最多使用一次
 * 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次，组合可以以任何顺序返回。
 * <p>
 * <p>
 * <p>
 * 示例 1:
 * <p>
 * 输入: k = 3, n = 7
 * 输出: [[1,2,4]]
 * 解释:
 * 1 + 2 + 4 = 7
 * 没有其他符合的组合了。
 * 示例 2:
 * <p>
 * 输入: k = 3, n = 9
 * 输出: [[1,2,6], [1,3,5], [2,3,4]]
 * 解释:
 * 1 + 2 + 6 = 9
 * 1 + 3 + 5 = 9
 * 2 + 3 + 4 = 9
 * 没有其他符合的组合了。
 * 示例 3:
 * <p>
 * 输入: k = 4, n = 1
 * 输出: []
 * 解释: 不存在有效的组合。
 * 在[1,9]范围内使用4个不同的数字，我们可以得到的最小和是1+2+3+4 = 10，因为10 > 1，没有有效的组合。
 */

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Leetcode216 {

    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> result = new ArrayList<>();
        dfs(1, n, k, new LinkedList<>(), result);
        return result;
    }


    private void dfs(int start, int n, int k, LinkedList<Integer> stack,
                     List<List<Integer>> result) {
        int sum = 0;
        for (Integer i : stack) {
            sum += i;
        }
        if (sum > n) {
            return;
        }
        if (stack.size() == k && sum == n) {
            result.add(new ArrayList<>(stack));
            return;
        }
        //        i = 1开始 4
        for (int i = start; i <= 9; i++) {
            if (stack.size() == k) {
                continue;
            }
            stack.push(i);
            dfs(i + 1, n, k, stack, result);
            // 回溯
            stack.pop();
        }

    }

    public static void main(String[] args) {
        List<List<Integer>> combine = new Leetcode216().combine(9, 3);
        System.out.println(combine);
        System.out.println(combine.size());
    }


}
